<template>
    <a-control-group class="a-input-password">
        <a-input-string class="c-w-100" :color="formItemHook.myColor" :size="formItemHook.mySize" :sharp="formItemHook.mySharp" :disabled="formItemHook.myDisabled" :clearable="props.clearable" :isInner="true" :type="state.isShowPassword ? 'text' : 'password'" @update:value="methods.input" :value="props.value" :placeholder="props.placeholder" :autoFocus="props.autoFocus" @focus="emit('focus')" @blur="$emit('blur')"></a-input-string>
        <a-button v-if="props.attachButtonShown" class="action c-f-shrink-0" :color="formItemHook.myColor" :size="formItemHook.mySize" :sharp="formItemHook.mySharp" :disabled="formItemHook.myDisabled" :square="true" @click="state.isShowPassword = !state.isShowPassword"><span class="fa" :class="state.isShowPassword ? 'fa-eye' : 'fa-eye-slash'"></span></a-button>
    </a-control-group>
</template>

<script setup lang="ts">
import AInputString from './AInputString.vue'
import AButton from './AButton.vue'
import AControlGroup from './AControlGroup.vue'
import { FormItemProvided, InputPropsType, Rule_maxLength, Rule_minLength } from '@/types'
import { computed, inject, onMounted, reactive, watch } from 'vue'
import { useInput } from '@/hooks/useInput'
import { useFormItem } from '@/hooks/useFormItem'

interface PropsType extends InputPropsType<string | undefined, Rule_minLength | Rule_maxLength> {
    clearable?: boolean
    placeholder?: string
    attachButtonShown?: boolean
    autoFocus?: boolean
}
const props = withDefaults(defineProps<PropsType>(), {
    value: undefined,
    color: undefined,
    disabled: undefined,
    size: undefined,
    sharp: undefined,
    rules: () => [],
    isInner: false,
    clearable: true,
    placeholder: undefined,
    attachButtonShown: false,
    autoFocus: false,
})

interface StateType {
    isShowPassword: boolean
}
const state = reactive<StateType>({
    isShowPassword: false
})

const diff = computed(() => {
    if (props.rules === undefined) {
        return undefined
    }
    let maxLengthRule = props.rules.find(a => a.name === 'maxLength') as Rule_maxLength | undefined
    if (!maxLengthRule) {
        return undefined
    }
    let valueLength = props.value?.length ?? 0
    return {
        valid: valueLength <= maxLengthRule.value,
        text: `${valueLength}/${maxLengthRule.value}`
    }
})

const inputHook = useInput(props)
const formItemHook = useFormItem(props)
const formItem = inject<FormItemProvided | undefined>('formItem', undefined)

watch(() => inputHook.validator.valid, () => {
    if (props.isInner) {
        return
    }
    emit('validate', [inputHook.validator.valid, inputHook.validator.errorMessage])
})
onMounted(() => {
    methods.setDiffResult()
})

const emit = defineEmits<{
    (e: 'update:value', value?: string): void
    (e: 'validate', result: [boolean?, string?]): Promise<void>
    (e: 'focus'): void
    (e: 'blur'): void
}>()

const methods = {
    input(val?: string) {
        emit('update:value', val)
    },
    setDiffResult() {
        formItem?.value.setDiffResult(diff.value?.valid, diff.value?.text)
    },
}
</script>